package de.gbeine.java.depview.model;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author gbeine
 *
 */
public class Package extends Element {

    /**
     *
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(Package.class);

    private final Set<Class> classes = new HashSet<Class>();

    // Set to true after building the dependencies
    private boolean dependenciesBuild = false;

    /**
     *
     * @param name
     */
    public Package(final String name) {
        super(name);
        if (Package.LOGGER.isDebugEnabled()) {
            Package.LOGGER.debug("New PackageElement: " + name);
        }
    }

    public void addClass(final Class ce) {
        this.classes.add(ce);
        ce.setParentPackage(this);
    }

    public Set<Class> getClasses() {
        return Collections.unmodifiableSet(this.classes);
    }

    public Set<Package> inboundDependencies() {
        return this.getDependencies().getInboundPackageDependencies();
    }

    public Set<Package> outboundDependencies() {
        return this.getDependencies().getOutboundPackageDependencies();
    }

    @Override
    public Dependencies getDependencies() {
        if (!this.dependenciesBuild) {
            if (Package.LOGGER.isDebugEnabled()) {
                Package.LOGGER.debug("No dependencies calculated yet for " + this.getName());
            }
            this.buildDependencies();
        }
        return super.getDependencies();
    }

    @Override
    public String toString() {
        return "Package: " + this.getName() + " Inbound Dependencies: " + this.getDependencies().getInboundPackageDependencies().size() + " Outbound dependencies: " + this.getDependencies().getOutboundPackageDependencies().size() + " Classes: " + this.classes.size();
    }

    private void buildDependencies() {
        if (Package.LOGGER.isDebugEnabled()) {
            Package.LOGGER.debug("Building dependencies");
        }
        for (Class ce : this.classes) {
            if (Package.LOGGER.isDebugEnabled()) {
                Package.LOGGER.debug("Dependencies for ClassElement: " + ce.getName());
            }
            // We need to make sure to get the dependencies from super class
            // This is to avoid endless recursion
            super.getDependencies().addDependencies(ce.getDependencies());
        }
    }

}
